﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using System.IO;

using MEFedMVVM.ViewModelLocator;
using Cinch;
using System.Configuration;
using System.Threading;

namespace Anata.Client
{

    /// <summary>
    /// Runtime implementation of the 
    /// Data service used by the <c>ImageLoaderViewModel</c> to obtain data
    /// </summary>
    [PartCreationPolicy(CreationPolicy.NonShared)]
    [ExportService(ServiceType.Runtime, typeof(ILayananCabangProvider))]
    public class LayananCabangProvider : ILayananCabangProvider
    {
        #region Data
        private BackgroundTaskManager<int, List<CabangLayanan>> multiFetchBgWorker =
            new BackgroundTaskManager<int, List<CabangLayanan>>();
        private BackgroundTaskManager<int, CabangLayanan> singleFetchBgWorker =
            new BackgroundTaskManager<int, CabangLayanan>();
        private BackgroundTaskManager<CabangLayanan, CabangLayanan> singleUpdateBgWorker =
            new BackgroundTaskManager<CabangLayanan, CabangLayanan>();
        #endregion



        #region Public Methods/Properties

        public void LazyFetchCabangLayanans(int page, Action<List<CabangLayanan>> callback)
        {
            multiFetchBgWorker.TaskFunc = (argument) =>
                {
                    return FetchCabangLayanansInternal(argument);
                };

            multiFetchBgWorker.CompletionAction = (result) =>
                {
                    callback(result);
                };

            multiFetchBgWorker.WorkerArgument = page;
            multiFetchBgWorker.RunBackgroundTask();

        }

        public void LazyFetchCabangLayanan(int idCabangLayanan, Action<CabangLayanan> callback)
        {
            singleFetchBgWorker.TaskFunc = (argument) =>
            {
                return FetchCabangLayananInternal(argument);
            };

            singleFetchBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            singleFetchBgWorker.WorkerArgument = idCabangLayanan;
            singleFetchBgWorker.RunBackgroundTask();

        }

        public void LazyUpdateCabangLayanan(CabangLayanan pCabangLayanan, Action<CabangLayanan> callback)
        {
            singleUpdateBgWorker.TaskFunc = (argument) =>
            {
                return UpdateCabangLayananInternal(argument);
            };

            singleUpdateBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            singleUpdateBgWorker.WorkerArgument = pCabangLayanan;
            singleUpdateBgWorker.RunBackgroundTask();

        }
        /// <summary>
        /// To allow this class to be unit tested stand alone
        /// See CinchV1 articles about Unit Testing for this
        /// Or comments in Cinch BackgroundTaskManager<T> class
        /// </summary>
        public BackgroundTaskManager<int, List<CabangLayanan>> MultiFetchBgWorker
        {
            get { return multiFetchBgWorker; }
        }
        public BackgroundTaskManager<int, CabangLayanan> SingleFetchBgWorker
        {
            get { return singleFetchBgWorker; }
        }
        public BackgroundTaskManager<CabangLayanan, CabangLayanan> SingleUpdateBgWorker
        {
            get { return singleUpdateBgWorker; }
        }

        #endregion

        #region Private Methods
        private List<CabangLayanan> FetchCabangLayanansInternal(int page)
        {
            List<CabangLayanan> cabangLayanans = new List<CabangLayanan>();
            //TODO: bener-bener konek ke database
            int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
            AnataEntities context = new AnataEntities();
            using (context)
            {
                IQueryable<CabangLayanan> cabangLayananQuery =
                    from cabangLayanan in context.CabangLayanan.Include("Layanan")
                    orderby cabangLayanan.Layanan.Nama
                    select cabangLayanan;
                cabangLayanans = cabangLayananQuery.Skip(page * pageSize).Take(pageSize).ToList();
            }
            return cabangLayanans;
        }



        private CabangLayanan FetchCabangLayananInternal(int idCabangLayanan)
        {
            CabangLayanan retval = new CabangLayanan();
            //AnataEntities context = new AnataEntities();
            //using (context)
            //{
            //    IQueryable<CabangLayanan> konsumenQuery =
            //        from konsumen in context.CabangLayanan
            //        orderby konsumen.Layanan.Nama
            //        where konsumen.IdCabangLayanan == idCabangLayanan
            //        select konsumen;
            //    retval = konsumenQuery.First();
            //}
            return retval;
        }



        private CabangLayanan UpdateCabangLayananInternal(CabangLayanan pCabangLayanan)
        {
            //using (AnataEntities context = new AnataEntities())
            //{
            //    if (pCabangLayanan.IdCabangLayanan == 0)
            //    {
            //        context.AddToCabangLayanan(pCabangLayanan);
            //    }
            //    else
            //    {
            //        context.Attach(pCabangLayanan);
            //        // If the SalesOrderDetailID is not 0, then the item is not new
            //        // and needs to be updated. Because we already added the 
            //        // updated object to the context we need to apply the original values.
            //        // If we attached originalItem to the context 
            //        // we would need to apply the current values:
            //        // context.ApplyCurrentValues("SalesOrderDetails", updatedItem);
            //        // Applying current or original values, changes the state 
            //        // of the attached object to Modified.
            //        context.ObjectStateManager.ChangeObjectState(pCabangLayanan, System.Data.EntityState.Modified);
            //    }
            //    context.SaveChanges();
            //}
            return pCabangLayanan;
        }
        #endregion

    }
}
